#include<stdio.h>

#include<unistd.h>

#include<string.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/wait.h>

#include"task.h"

typedef void(*func_t)();//定义一个函数指针类型
                        
//想让父进程完成的任务
#define N 3
func_t task[N] = {NULL};


//加载任务
void LoadTask() //函数名就是函数的地址，此时将地址交给这个函数指针，此时相当于有一张函数表
{
  task[0] = PrintLog;

  task[1] = Download;

  task[2] =  MysqlDataSync;
}

//处理凡是在任务列表中的任务
void HandlerTask()
{
  for(int i = 0; i < N; i++)
  {
    task[i]();
  }

}

//做除了等待子进程外的其他任务
void DoOtherThing()
{
  
  HandlerTask();

}






void ChildRun()
{
  //int* p = NULL;
  int cnt = 5;
  while(cnt)
  {
    printf("i'm child process, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);
    sleep(1);
    cnt--;
   // *p = 100;
    
  }
}


int main()
{
	printf("I am father, pid: %d, ppid: %d\n", getpid(), getppid());
    pid_t id = fork();
    if(id == 0)
    {
      //child
      ChildRun();
      printf("child quit ...\n");
      exit(123);
    }

    //启动父进程之前，先加载任务：
    LoadTask();
    //father
    //循环对子进程的状态进行访问
    while(1)
    {
      int status = 0;
      pid_t rid = waitpid(id, &status, WNOHANG);//非阻塞 non block
      //查询到子进程状态，但是子进程还没有退出
      if(rid == 0)
      {
        usleep(1000);
        printf("child is running, father check next time!\n");
        DoOtherThing();
      }//等待子进程退出成功
      else if( rid == id)
      {
      //检测是否是正常退出
        if(WIFEXITED(status))
        {
          printf("child  quit success, child quit code: %d\n", WEXITSTATUS(status));
        }
        else
        {
         
          printf("child quit unnormal\n");
        }
        break;
      }
      else
      {
        printf("waitpid failed!\n");
      }
    }
























     

    //father
    //sleep(15);
    //pid_t rid = wait(NULL);
    //pid_t waitpid(pid_t pid, int* wstatus, int options) ;   
 
//    int status = 0;
//    pid_t rid = waitpid(id, &status, 0);
//    if(rid > 0)
//    {
//      if(WIFEXITED(status))
//      {
//        printf("child  quit success, child quit code: %d\n", WEXITSTATUS(status));
//      }
//      else
//      {
//        printf("child quit unnormal\n");
//      }
//
//      printf("wait Success, rid: %d\n", rid);
//
//    }
//    else
//    {
//      printf("wait fail!\n");
//    }
//
//    sleep(3);
    //printf("father quit, status: %d, child quit code: %d, child quit signal: %d\n", status, )
    //printf("father  quit ..., status: %d\n", status);
	//return 0;
}



//自定义枚举常量
//enum
//{
//	Success = 0,
//	DIV_ZERO,
//	Mod_Zero,
//};
//int exit_code = Success;
//
//const char* CodeToErrString(int code)
//{
//	switch(code)
//	{
//		case Success:
//			return "Success!";
//		case DIV_ZERO:
//			return "div zero!";
//		case Mod_Zero:
//			return "mod zero!";
//		default:
//			return "unknown error!";
//	}
//}
//
//int Div(int x, int y)
//{
//	if( 0 == y)
//	{
//		exit_code = DIV_ZERO;
//		return -1;
//	}
//	else
//	{
//		return x / y;
//	}
//}
//
//int main()
//{
// 	int result = 0;
//	result = Div(10, 5);
//	printf("result = %d [%s]\n", result, CodeToErrString(exit_code));
//	result = Div(10, 0);
//	printf("result = %d [%s]\n", result, CodeToErrString(exit_code));
//	sleep(1);
//	return 0;
//}
